package com.example.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.PageResult;
import com.example.dto.SOrderDTO;
import com.example.entity.AliPay;
import com.example.entity.SOrder;
import com.example.entity.SSku;
import com.example.entity.User;
import com.example.exception.CustomException;
import com.example.mapper.SOrderMapper;
import com.example.mapper.SSkuMapper;
import com.example.mapper.UserMapper;
import com.example.service.SOrderService;
import com.example.vo.SOrderVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.example.common.OrderConstant.*;


/**
 * <p>
 * 新订单表 服务实现类
 * </p>
 *
 * @author zh
 * @since 2024-05-13 10:36:29
 */
@Service
public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> implements SOrderService {
    @Autowired
    private SOrderMapper sOrderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private SSkuMapper sSkuMapper;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Override
    public SOrderVO getSOderDetail(Long orderId) {
        SOrder sOrder = sOrderMapper.selectById(orderId);
        SOrderVO sOrderVO = BeanUtil.copyProperties(sOrder, SOrderVO.class);
        String stateName = ORDER_STATE_MAP.get(sOrderVO.getState());
        sOrderVO.setStateName(stateName);
//        订单人信息
        return sOrderVO;
    }

    @Override
    public void submitSOrder(SOrderDTO orderDTO) {
        SOrder sOrder = BeanUtil.copyProperties(orderDTO, SOrder.class);
        sOrder.setState(0);
        sOrder.setUnpaidTime(LocalDateTime.now());
        sOrderMapper.insert(sOrder);
    }

    @Override
    public String updateState(Long orderId, Integer state) {
        SOrder sOrder = sOrderMapper.selectById(orderId);
//        sOrder.setId(orderId);
        sOrder.setState(state);

        switch (state) {
            case ORDER_UNPAID:
                sOrder.setUnpaidTime(LocalDateTime.now());
                break;
            case ORDER_PRE_DELIVERY:
                sOrder.setPreDeliveryTime(LocalDateTime.now());
                break;
            case ORDER_DELIVERY:
                sOrder.setDeliveryTime(LocalDateTime.now());
                break;
            case ORDER_PRE_RECEIVE:
                sOrder.setPreReceiveTime(LocalDateTime.now());
                break;
            case ORDER_RECEIVE:
                sOrder.setReceiveTime(LocalDateTime.now());
                break;
            case ORDER_COMMENT:
                sOrder.setCommentTime(LocalDateTime.now());
                break;
            case ORDER_PRE_RETURN:
                sOrder.setPreReturnTime(LocalDateTime.now());
                break;
            case ORDER_RETURN:
                sOrder.setReturnTime(LocalDateTime.now());
                break;
            default:
                throw new CustomException("-1", "状态码不正确");
        }
        if(state == ORDER_DELIVERY){
            SSku sSku = sSkuMapper.selectById(sOrder.getSkuId());
            if (sSku.getStock() - sOrder.getCount()<0){
                return "库存不足";
            }
            sSku.setStock(sSku.getStock() - sOrder.getCount());
            sSkuMapper.updateById(sSku);
            String key = "spu:" + sSku.getSpuId() + ":skuList";
            redisTemplate.delete(key);
        }
        sOrder.setUpdateTime(LocalDateTime.now());
        sOrderMapper.updateById(sOrder);
        return "success";
    }

    @Override
    public PageResult<SOrderVO> pageOrder(Integer pageNum, Integer pageSize, Long orderId, LocalDateTime startTime,
                                          LocalDateTime endTime, Integer state, Long userId) {
        PageHelper.startPage(pageNum, pageSize);
        List<SOrder> sOrderList = sOrderMapper.page(orderId, startTime, endTime, state, userId);
        PageInfo<SOrder> pageInfo = new PageInfo<>(sOrderList);
        List<SOrder> sOrders = pageInfo.getList();
        List<Long> userIds = sOrders.stream().map(SOrder::getUserId).collect(Collectors.toList());
//        没有该状态的订单了
        if (userIds.isEmpty()) {
            return PageResult.<SOrderVO>builder()
                    .current((long) pageInfo.getPageNum())
                    .size(0)
                    .total(pageInfo.getTotal())
                    .records(new ArrayList<SOrderVO>())
                    .build();
        }
        List<User> userList = userMapper.selectBatchIds(userIds);
        // 创建一个 Map 来快速通过用户ID查找用户
        Map<Long, User> userIdToUserMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
        List<SOrderVO> sOrderVOList = sOrders.stream().map(sOrder -> {
//
            SOrderVO sOrderVO = BeanUtil.copyProperties(sOrder, SOrderVO.class);
            sOrderVO.setStateName(ORDER_STATE_MAP.get(sOrderVO.getState()));
            // 从 Map 中通过用户ID查找用户，并设置到 SOrderVO 中
            User user = userIdToUserMap.get(sOrder.getUserId());
            if (user != null) {
//                剔除敏感信息
                user.setPassword("");
                user.setSalt("");
                user.setRole(new ArrayList<>());
                user.setPermission(new ArrayList<>());
                user.setToken("");
                sOrderVO.setUser(user); // 假设 SOrderVO 有一个 setUser 方法
            }
            return sOrderVO;
        }).collect(Collectors.toList());
        //分页结果
        return PageResult.<SOrderVO>builder()
                .current((long) pageInfo.getPageNum())
                .size((long) sOrderVOList.size())
                .total(pageInfo.getTotal())
                .records(sOrderVOList)
                .build();
    }

    @Override
    public Map<String, Long> orderCount(Long userId) {
        List<Map<Integer, Long>> maps = sOrderMapper.countByState(userId);
        Map<String, Long> countMap = new HashMap<>();
        for (Map<Integer, Long> map : maps) {
            countMap.put(ORDER_STATE_MAP.get(map.get("state")), map.get("count"));
        }
        return countMap;
    }

    /**
     * 多条订单插入
     *
     * @param sOrders
     */
    @Override
    public List<SOrder> submitSOrderBatch(List<SOrder> sOrders) {
       
//        同步
        synchronized (this) {
            List<Long> ids = new ArrayList<>();
//            每插入一条，取出这一条订单的id
            for (SOrder sOrder : sOrders) {
                sOrder.setState(0);
                sOrder.setUnpaidTime(LocalDateTime.now());
                sOrderMapper.insert(sOrder);
                ids.add(sOrder.getId());
            }
//            返回刚刚插入的订单，重点数据:id ,payPrice
            return sOrderMapper.selectBatchIds(ids);
        }
    }

    @Override
    public void cancelOrder(Long orderId) {
        sOrderMapper.deleteById(orderId);
    }

    /**
     * 将订单转为AliPay
     *
     * @param sOrders
     */
    @Override
    public AliPay changeOrderToAliPay(List<SOrder> sOrders) {
        String collect = sOrders.stream()
                .map(sOrder -> String.valueOf(sOrder.getId()))
                .collect(Collectors.joining(":"));
        BigDecimal sum = new BigDecimal("0");
        for (SOrder sOrder : sOrders) {
            sum = sum.add(sOrder.getPayPrice());
        }
        AliPay aliPay = new AliPay();
        aliPay.setTraceNo(collect);
        aliPay.setTotalAmount(sum.toString());
        aliPay.setSubject("鞋子");
        return aliPay;
    }

    /**
     * 根据id，把订单的状态由未支付（0）变为待收货（已支付）（1）
     *
     * @param ids
     */
    @Override
    public int updateOrderState(List<Long> ids,String payMethod) {
        // 创建UpdateWrapper
        UpdateWrapper<SOrder> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().in(SOrder::getId, ids) // 设置更新条件，这里以id为条件
                .set(SOrder::getState, 1)
                .set(SOrder::getPreDeliveryTime, LocalDateTime.now())
                .set(SOrder::getPayMethod,payMethod); // 设置要更新的字段名和值
        // 执行更新操作
        int update = sOrderMapper.update(null, updateWrapper);
        return update;
    }

    @Override
    public void returnSOrder(Long orderId, String reason) {
        LambdaUpdateWrapper<SOrder> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(SOrder::getId, orderId)
                .set(SOrder::getState, -1)
                .set(SOrder::getReturnReason, reason)
                .set(SOrder::getPreReturnTime, LocalDateTime.now());
        sOrderMapper.update(wrapper);
    }

}
